/*
 * @FileName: app_calibration.c
 * @Author: GreyQiu qiushaogui@aikosolar.com
 * @Date: 2023-08-21 10:50:15
 * @LastEditors: GreyQiu qiushaogui@aikosolar.com
 * @LastEditTime: 2023-11-09 17:24:17
 * @Description: 
 * 
 * Copyright (c) 2023, All Rights Reserved. 
 */
#include "app_calibration.h"
#include "app_fault.h"
#include "app_fsm.h"
#include "app_analog.h"
#include "log.h"
#include "mbreg.h"
#include "loop.h"

uint16_t coff_save_flag = 0;

flash_obj_t app_data;
fsbb_info_t fsbb_info; // 掉电保存信息的RAM映射

void app_calib_init(void)
{
//    uint16_t reset_flag = 0;
//    uint16_t save_flag = 0;
//    uint16_t i;

//    /* 从FLASH中读取FSBB保存参数 */
//    bsp_flash_obj_init(&app_data, DEVICE_DATA_ADDR, DEVICE_DATA_SIZE);
//    bsp_flash_read(&app_data, 0, (uint8_t *)(&fsbb_info), sizeof(fsbb_info_t));

//    /* 检查参数合法性，若不合法，赋默认值 */
//    if (fsbb_info.factoryCode != 0x1234) {    // 需要恢复出场设置
//        reset_flag = 1;
//    }
//    /* 1、检查最大电压 */
//    if (fsbb_info.maxVout > 30000 || fsbb_info.maxVout < 5000) { // 最大输出电压范围5V~30V
//        reset_flag = 1;
//    }

//    /* 2、检查最大电流 */
//    if (fsbb_info.maxIout > 7000 || fsbb_info.maxIout < 1000) { // 最大输出电压范围1A~7A
//        reset_flag = 1;
//    }

//    /* 4、检查校准系数 */
//    for (i = 0; i < FACTOR_IDX_NUM; i++) {
//        if (fsbb_info.factor[i].k > FACTOR_K_MAX || fsbb_info.factor[i].k < FACTOR_K_MIN) {
//            reset_flag = 1;
//        }

//        if (fsbb_info.factor[i].b > FACTOR_B_MAX || fsbb_info.factor[i].b < FACTOR_B_MIN) {
//            reset_flag = 1;
//        }

////        if (reset_flag == 1)
////        {
////            fsbb_info.factor[i].k = FACTOR_K_DEFAULT;
////            fsbb_info.factor[i].b = FACTOR_B_DEFAULT;
////            save_flag = 1; 
////        }
//        log_debug("%d k = %d, b = %d\n", i, fsbb_info.factor[i].k, fsbb_info.factor[i].b);
//    }

//    if (reset_flag == 1) {
//        fsbb_info.factoryCode = 0x1234;
//        fsbb_info.version = 102;
//        fsbb_info.maxVout = 30000;
//        fsbb_info.maxIout = 7000;
//        fsbb_info.maxPout = 110;
//        fsbb_info.distVout = 30;
//        fsbb_info.distIout = 10;

//        for (i = 0; i < FACTOR_IDX_NUM; i++) {
//            fsbb_info.factor[i].k = FACTOR_K_DEFAULT;
//            fsbb_info.factor[i].b = FACTOR_B_DEFAULT;
//        }

//        bsp_flash_page_erase(&app_data, 0, 1); // 擦除
//        bsp_flash_write(&app_data, 0, (uint8_t *)(&fsbb_info), sizeof(fsbb_info_t)); // 写入
//    }

//    // 初始化各采样校准系数
//    for (i = 0; i < FACTOR_IDX_NUM; i++) {
//        analog_tbl[i].k1 =  0.0001f * fsbb_info.factor[i].k;
//        analog_tbl[i].b1 =  0.0001f * fsbb_info.factor[i].b;
//    }
}


ErrorStatus app_calib_config(uint8_t id, uint16_t k, int16_t b)
{
//    log_debug("%d app_calib_config k = %d b = %d\n", id, k, b);
//    if (id >= FACTOR_IDX_NUM) {
//        return ERROR;
//    }

//    if (k > FACTOR_K_MAX || k < FACTOR_K_MIN) {
//        return ERROR;
//    }

//    if (b > FACTOR_B_MAX || b < FACTOR_B_MIN) {
//        return ERROR;
//    }

//    fsbb_info.factor[id].k = k;
//    fsbb_info.factor[id].b = b;

//    analog_tbl[id].k1 =  0.0001f * fsbb_info.factor[id].k;
//    analog_tbl[id].b1 =  0.0001f * fsbb_info.factor[id].b;

////    // if (id == FACTOR_IDX_IOUT) {
////        bsp_flash_page_erase(&app_data, 0, 1); // 擦除
////        bsp_flash_write(&app_data, 0, (uint8_t *)factor, sizeof(calibration_t) * FACTOR_IDX_NUM); // 写入
////    // }

//    return SUCCESS;
}



unsigned int SgetCRC16_1D0F( unsigned char *ptr, unsigned char len)
{
    unsigned char i;
    unsigned int crc=0xFFFF;
    if(len==0)
       len=2;//
    while(len--)
    {
        //WDR();
        crc^=*ptr;
            for(i=0; i<8; i++)
       {
                   if(crc&1)
             {
             crc>>=1;
             crc^=0x1D0F;
           }
           else
             crc>>=1;
                }
             ptr++;
           }
     return(crc);


}

uint8_t dat[16];
//上位机通过串口发送 PRUDUCT_CATEGORY（16b），DEVICE_TYPE(16b)，uniqID(32b)过来，计算出key3后发送过去或者等上位机召唤。通信协议要预留key1、KEY2、KEY3的位置。key1/2/3都是32b。
//计算key3 的步骤，先把发过来的数据整理成数组 dat，顺序见程序。之后做两组CRC16，key3由KEYH和KEYL组成。
//目前是只用了KEY3.
void sActiveProc(void)
{
    //unsigned int keyH,keyL;
    //unsigned char dat[16];
    #define JYSN    0x4a59534e
    #define JETG    0x4a455447

    dat[0] = (mbHoldingReg[MB_REG_UNIQID_H] >> 8) & 0x00ff;
    dat[1] = mbHoldingReg[MB_REG_UNIQID_H] & 0x00ff;
    dat[2] = (mbHoldingReg[MB_REG_UNIQID_L] >> 8) & 0x00ff;
    dat[3] = mbHoldingReg[MB_REG_UNIQID_L] & 0x00ff;

    dat[4] = (JYSN >> 24) & 0x00ff;
    dat[5] = (JYSN >> 16) & 0x00ff;
    dat[6] = (JYSN >> 8) & 0x00ff;
    dat[7] = JYSN & 0x00ff;

    mbHoldingReg[MB_REG_KEY3H] = SgetCRC16_1D0F(dat,8);

    dat[8] = (mbHoldingReg[MB_REG_PRUDUCT_CATEGORY] >> 8) & 0x00ff;
    dat[9] = (mbHoldingReg[MB_REG_PRUDUCT_CATEGORY] >> 0) & 0x00ff;
    dat[10] = (mbHoldingReg[MB_REG_DEVICE_TYPE] >> 8) & 0x00ff;
    dat[11] = mbHoldingReg[MB_REG_DEVICE_TYPE] & 0x00ff;

    dat[12] = (JETG >> 24) & 0x00ff;
    dat[13] = (JETG >> 16) & 0x00ff;
    dat[14] = (JETG >> 8) & 0x00ff;
    dat[15] = JETG & 0x00ff;

    mbHoldingReg[MB_REG_KEY3L] = SgetCRC16_1D0F(dat,16);

}

void fsbb_info_updata(void)
{
    if (mbHoldingReg[MB_REG_START_DONGLE] == 0x5A5A) {
        sActiveProc();
        mbHoldingReg[MB_REG_START_DONGLE] = 0;
    }
    
    if (mbHoldingReg[MB_REG_CLEAR] == 0x5A5A) {
        for (uint16_t i = 0; i < MB_REG_NUM; i++) {
            mbHoldingReg[i] = 0;
        }
        mbHoldingReg[MB_REG_CLEAR] = 0;
    }
}